package com.shinewind.home.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shinewind.common.constant.messageConstant;
import com.shinewind.home.service.*;
import com.shinewind.pojo.dto.AdminArticleDto;
import com.shinewind.pojo.dto.AdminModelDto;
import com.shinewind.pojo.entity.*;
import com.shinewind.pojo.result.Result;
import com.shinewind.pojo.vo.AdminModelListVo;
import com.shinewind.pojo.vo.AdminUserListVo;
import com.shinewind.pojo.vo.PageVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@DubboService
public class ModelAdminServiceImpl implements IModelAdminService {
    @Autowired
    private IBrandService iBrandService;
    @Autowired
    private IModelService iModelService;
    @Autowired
    private IStatusService iStatusService;
    @Autowired
    private IModelMappingService iModelMappingService;
    @Autowired
    private INewsService iNewsService;

    @Override
    public PageVo<Brand> getModelBrandList(Integer current, Integer pageSize) {
        IPage page = new Page<Brand>(current,pageSize);
        List<Brand> brandList = iBrandService.page(page).getRecords();
        if(brandList.size() > 0)
            return new PageVo<Brand>(brandList,true, messageConstant.QUERY_SUCCESS, (int) page.getTotal());
        else
           return new PageVo<Brand>(null,false,messageConstant.QUERY_ERROR, (int) page.getTotal());
    }

    @Override
    public PageVo<AdminModelListVo> getModelList(Integer current, Integer pageSize, String title,
                                         String typeName, String saleTime, String price) {
        List<Model> modelList;
        System.out.println("title:"+title);
        System.out.println("typeName:"+typeName);
        System.out.println("saleTime:"+saleTime);
        System.out.println("price:"+price);
        if((title != null && !title.trim().equals("")) || (typeName != null && !typeName.trim().equals("")) ||
            (saleTime != null && !saleTime.trim().equals("")) || (price != null && !price.trim().equals(""))){
            //处理price的数据格式
            if((price != null && !price.trim().equals(""))){
                String[] priceFormat = price.split(",");
                String startPrice = priceFormat[0];
                String endPrice = !"10000".equals(startPrice) ? priceFormat[1] : "";
                System.out.println("priceFormat:"+priceFormat);
                modelList = iModelService.lambdaQuery().and((title != null && !title.trim().equals(""))
                                || (typeName != null && !typeName.trim().equals("") ||
                                (price != null && !price.trim().equals(""))),
                                i ->
                                i.like(title != null && !title.trim().equals(""),
                                Model::getTitle,title)
                                .eq(typeName != null && !typeName.trim().equals(""),
                                Model::getBId,typeName)
                                .between(price != null && !price.trim().equals("") &&
                                !startPrice.trim().equals("10000"),
                                Model::getPrice,startPrice,endPrice)
                                .gt(price != null && !price.trim().equals("") &&
                                startPrice.trim().equals("10000"),
                                Model::getPrice,startPrice))
                                .list();
            }
            else{
                modelList = iModelService.lambdaQuery()
                                .and((title != null && !title.trim().equals(""))
                                || (typeName != null && !typeName.trim().equals("")),
                                i ->
                                i.like(title != null && !title.trim().equals(""),
                                Model::getTitle,title)
                                .eq(typeName != null && !typeName.trim().equals(""),
                                Model::getBId,typeName))
                                .list();
            }
        }
        else{
            modelList = iModelService.lambdaQuery().list();
        }

        List<AdminModelListVo> modelListVoList = modelList.stream().map(model -> {
            AdminModelListVo adminModelListVo = AdminModelListVo.builder().build();
            BeanUtils.copyProperties(model,adminModelListVo);
            //模型品牌
            if(typeName != null && !typeName.trim().equals("")){
                String brand = iBrandService.getBrandInfoById(Integer.parseInt(typeName)).getBrand();
                adminModelListVo.setBrand(brand);
            }
            else{
                 String brand= iBrandService.getBrandInfoById(model.getBId()).getBrand();
                 adminModelListVo.setBrand(brand);
            }
            //模型发售时间
            List<Status> StatusList = iStatusService.lambdaQuery().eq(Status::getMId, model.getMId())
                    .orderByDesc(Status::getSaleTime).list();
            List<String> saleTimeList = new ArrayList<>();
            for (Status status : StatusList) {
                if (StatusList.size() >= 1 && !StrUtil.isEmpty(status.getSaleTime().toString())) {
                    StringBuilder dateStr = new StringBuilder(DateUtil.format(status.getSaleTime(), "yyyy-MM-dd"));
                    saleTimeList.add(dateStr.toString());
                }
            }
            adminModelListVo.setSaleTime(saleTimeList);
            return adminModelListVo;
        }).collect(Collectors.toList());
        //处理saleTime的数据格式
        if(saleTime != null){
            String[] saleTimeFormat = saleTime.split(",");
            String startTime = saleTimeFormat[0];
            String endTime = saleTimeFormat[1];
            System.out.println("startTime:"+startTime);
            System.out.println("endTime:"+endTime);
            modelListVoList = modelListVoList.stream().filter(modelVo -> {
                for(String time : modelVo.getSaleTime()){
                    System.out.println("time:"+time);
                    System.out.println("flag:"+DateUtil.isIn(DateUtil.parseDate(time),
                            DateUtil.parseDate(startTime),DateUtil.parseDate(endTime)));
                    return DateUtil.isIn(DateUtil.parseDate(time),DateUtil.parseDate(startTime),DateUtil.parseDate(endTime));
                }
                return false;
            }).distinct().collect(Collectors.toList());
        }
        Integer total = modelListVoList.size();
        if(modelListVoList.size() > 0){
            modelListVoList = ListUtil.page(current-1,pageSize,modelListVoList);
            return new PageVo<AdminModelListVo>(modelListVoList, BooleanUtil.isTrue(modelListVoList.size() > 0),
                    messageConstant.QUERY_SUCCESS, total);
        }
        else{
            return new PageVo<AdminModelListVo>(modelListVoList,BooleanUtil.isFalse(modelListVoList.size() == 0),
                    messageConstant.QUERY_NULL, total);
        }
    }

    @Override
    public PageVo<Brand> getModelBrandListByKeyWord(Integer current, Integer pageSize, String keyWord) {
        IPage page = new Page<Brand>(current,pageSize);
        List<Brand> brandList = iBrandService.lambdaQuery().like(keyWord != null && !keyWord.trim().equals(""),
                Brand::getBrand,keyWord).page(page).getRecords();
        //if(brandList.size() > 0)
            return new PageVo<Brand>(brandList,true, messageConstant.QUERY_SUCCESS, (int) page.getTotal());
        /*else
            return new PageVo<Brand>(null,false,messageConstant.QUERY_ERROR, (int) page.getTotal());*/
    }

    @Override
    public Result getAdminModelDetailByMid(String mId) {
        Model model = iModelService.getModelByMId(mId);
        AdminModelListVo adminModelListVo = AdminModelListVo.builder().build();
        BeanUtils.copyProperties(model,adminModelListVo);
        //品牌
        String brand = iBrandService.getBrandInfoById(model.getBId()).getBrand();
        adminModelListVo.setBrand(brand);
        //发售时间
        List<Status> StatusList = iStatusService.lambdaQuery().eq(Status::getMId, model.getMId())
                .orderByDesc(Status::getSaleTime).list();
        List<String> saleTimeList = new ArrayList<>();
        for (Status status : StatusList) {
            if (StatusList.size() >= 1 && !StrUtil.isEmpty(status.getSaleTime().toString())) {
                StringBuilder dateStr = new StringBuilder(DateUtil.format(status.getSaleTime(), "yyyy-MM-dd"));
                saleTimeList.add(dateStr.toString());
            }
        }
        adminModelListVo.setSaleTime(saleTimeList);
        if(ObjectUtil.isNotNull(adminModelListVo)){
            return Result.success(adminModelListVo,true,messageConstant.QUERY_SUCCESS);
        }
        return Result.fail(false,messageConstant.QUERY_ERROR);
    }

    @Override
    public Model addModel(AdminModelDto adminModelDto) {
        //添加model表中的内容
        Model model = Model.builder().build();
        BeanUtils.copyProperties(adminModelDto,model);
        Boolean flag = iModelService.save(model);
        if(flag){
            //添加mapping
            iModelMappingService.save(ModelMapping.builder().mId(model.getMId()).build());
            //如果传递了发售时间，则添加发售时间
            if(adminModelDto.getSaleTime().size() != 0){
                List<Map<String,Object>> saleTime = adminModelDto.getSaleTime();
                List<Status> statusList = saleTime.stream().map(time -> {
                    Status status = Status.builder().build();
                    status.setStatus("发售");
                    status.setSaleTime(DateUtil.parseDate(time.get("value").toString()));
                    status.setMId(model.getMId());
                    return status;
                }).collect(Collectors.toList());
                System.out.println("statusList:"+statusList);
                iStatusService.saveBatch(statusList);
            }
            return model;
        }
        else{
            return null;
        }
    }

    @Override
    public Model getModelInfo(String mId) {
        Model model = iModelService.lambdaQuery().eq(Model::getMId,mId).one();
        return model;
    }

    @Override
    public List<Map<String, Object>> getStatusByMid(String mId) {
        List<Status> statusList = iStatusService.lambdaQuery().eq(Status::getMId,mId).list();
        List<Map<String,Object>> list = statusList.stream().map(status -> {
            Map<String,Object> objectMap = new HashMap<>();
            objectMap.put("sId",status.getSId());
            objectMap.put("value",status.getSaleTime());
            return objectMap;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public Boolean updateModel(String mId, AdminModelDto adminModelDto) {
        //修改model表信息
        Model model = Model.builder().mId(mId).build();
        BeanUtils.copyProperties(adminModelDto,model);
        Boolean flag = iModelService.lambdaUpdate().eq(Model::getMId,mId).update(model);
        if(flag){
            //修改发售时间
            //前端更改的发售时间
            List<Status> saleTime = adminModelDto.getSaleTime().stream()
                    .map(time -> {
                        Status status = Status.builder().build();
                        status.setStatus("发售");
                        status.setSaleTime(DateUtil.parseDate(time.get("value").toString()));
                        status.setMId(model.getMId());
                        return status;
                    })
                    .distinct()
                    .collect(Collectors.toList());
            //删除后端发售时间
            iStatusService.lambdaUpdate().eq(Status::getMId,mId).remove();
            //添加前端发售时间
            return iStatusService.saveBatch(saleTime);
        }
        return flag;
    }

    @Override
    public Boolean deleteModel(String mId) {
        //删除model表内容
        Boolean flag1 = iModelService.lambdaUpdate().eq(Model::getMId,mId).remove();
        //删除modelMapping表内容
        Boolean flag2 = iModelMappingService.lambdaUpdate().eq(ModelMapping::getMId,mId).remove();
        //删除status表内容
        Boolean flag3 = iStatusService.lambdaUpdate().eq(Status::getMId,mId).remove();
        if(flag1 && flag2 && flag3)
            return true;
        else
            return false;
    }

    @Override
    public String getArticleStatusByMid(String mId) {
        if(iNewsService.lambdaQuery().eq(News::getId,mId).count() > 0){
            News news = iNewsService.lambdaQuery().eq(News::getId,mId).one();
            if(news.getIsModel().equals("0"))
                return "新闻";
            else if(news.getIsModel().equals("1"))
                return "模型";
            else if(news.getIsModel().equals("2"))
                return "活动";
        }
        else
            return "模型";
        return "未知错误";
    }

    @Override
    public News getNewsInfo(String id) {
        News news = iNewsService.lambdaQuery().eq(News::getId,id).one();
        return news;
    }

    @Override
    public PageVo<AdminModelListVo> getModelMidList(Integer current, Integer pageSize) {
        IPage page = new Page<AdminModelListVo>(current,pageSize);
        List<AdminModelListVo> adminModelListVos = iModelService.lambdaQuery().page(page).getRecords();
        return new PageVo<AdminModelListVo>(adminModelListVos,true,messageConstant.QUERY_SUCCESS, (int) page.getTotal());
    }

    @Override
    public PageVo<AdminModelListVo> getModelMidListByKeyWord(Integer current, Integer pageSize, String keyWord) {
        IPage page = new Page<AdminModelListVo>(current,pageSize);
        List<AdminModelListVo> adminModelListVos = iModelService.lambdaQuery().like(keyWord != null &&
                                    !keyWord.trim().equals(""),Model::getTitle,keyWord)
                                    .page(page).getRecords();
        return new PageVo<AdminModelListVo>(adminModelListVos,true,messageConstant.QUERY_SUCCESS, (int) page.getTotal());
    }

    @Override
    public News addNewsInfo(AdminArticleDto adminArticleDto) {
        //将信息写入news表
        News news = News.builder().build();
        BeanUtils.copyProperties(adminArticleDto,news);
        news.setIsModel("0");
        Boolean flag = iNewsService.save(news);
        if(flag){
            return news;
        }
        else{
            return null;
        }
    }

    @Override
    public Long getModelCount(String mId) {
        return iModelService.lambdaQuery().eq(Model::getMId,mId).count();
    }

    @Override
    public List<AdminModelListVo> getModelMidUpdateList(Integer current, Integer pageSize) {
        IPage page = new Page<AdminModelListVo>(current,pageSize);
        List<Model> modelList = iModelService.lambdaQuery().list();
        List<AdminModelListVo> adminModelListVos = modelList.stream().map(model -> {
            AdminModelListVo adminModelListVo = AdminModelListVo.builder().build();
            BeanUtils.copyProperties(model,adminModelListVo);
            return adminModelListVo;
        }).collect(Collectors.toList());
        List<News> news = iNewsService.lambdaQuery().list();
        List<AdminModelListVo> adminModelListVoList = news.stream().map(newsInfo -> {
            AdminModelListVo adminModelListVo = AdminModelListVo.builder().build();
            BeanUtils.copyProperties(newsInfo,adminModelListVo);
            adminModelListVo.setMId(newsInfo.getId());
            adminModelListVo.setTitle(newsInfo.getTitle());
            return adminModelListVo;
        }).collect(Collectors.toList());
        List<AdminModelListVo> resultList = CollectionUtil.union(adminModelListVos,adminModelListVoList).stream().distinct()
                .collect(Collectors.toList());
        return resultList;
    }

    @Override
    public Boolean updateNewsInfo(AdminArticleDto adminArticleDto) {
        return iNewsService.lambdaUpdate().eq(News::getId,adminArticleDto.getMId())
                .set(News::getTitle,adminArticleDto.getTitle())
                .set(News::getSrc,adminArticleDto.getSrc())
                .set(News::getHref,adminArticleDto.getHref())
                .update();
    }

    @Override
    public Boolean deleteNewsByid(String mId) {
        return iNewsService.lambdaUpdate().eq(News::getId,mId).remove();
    }
}
